package com.ddf.norman.config;

import com.ddf.norman.util.HashPasswordEncoder;
import com.ddf.publics.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;


import javax.sql.DataSource;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    //注入服务层
    @Autowired
    private LoginService userDetailsService;

    //注入密码加密类
    @Autowired
    private HashPasswordEncoder hashPasswordEncoder;

    //注入数据源
    @Autowired
    DataSource dataSource;

    //登录成功的处理类
    @Autowired
    private UserLoginAuthenticationSuccessHandler userLoginAuthenticationSuccessHandler;

    //登录失败的处理类
    @Autowired
    private UserLoginAuthenticationFailureHandler userLoginAuthenticationFailureHandler;

    //注入数据源
    @Bean
    public PersistentTokenRepository persistentTokenRepository() {
     JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
     // 配置数据源
     jdbcTokenRepository.setDataSource(dataSource);
     // 第一次启动的时候自动建表（可以不用这句话，自己手动建表，源码中有语句的）
     //jdbcTokenRepository.setCreateTableOnStartup(true);
     return jdbcTokenRepository;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/qqLogin","/qqBinding","/sendBindingCode","/bindingUser","/","/index","/userLogin","/register","/sendRegisterVerify","/userRegister","/forgot","/sendForgotVerify","/userForgot","/newGuider")//登录和注册不需要拦截
                .permitAll()//不需要身份认证
                .anyRequest().authenticated();//其他路径必须验证身份
        //springSecurty使用X-Frame-Options防止网页被Frame
        http.headers().frameOptions().disable();
        http
                .formLogin()
                .loginPage("/login")//登录页面，加载登录的html页面
                .loginProcessingUrl("/userLogin")//发送Ajax请求的路径
                .permitAll()
                .usernameParameter("phone")//请求验证参数
                .passwordParameter("password")//请求验证参数.failureHandler(userLoginAuthenticationFailureHandler)//验证失败处理
                .successHandler(userLoginAuthenticationSuccessHandler)//验证成功处理
                .failureHandler(userLoginAuthenticationFailureHandler)
                .and()
                .rememberMe()
                .rememberMeParameter("remember-me")
                .tokenRepository(persistentTokenRepository())
                .tokenValiditySeconds(1000*60*60)//设置Token的有效时间
                .userDetailsService(this.userDetailsService);//使用userDetailsService用Token从数据库中获取用户自动登录
        http.logout();
        http.csrf().disable();
        http.sessionManagement().maximumSessions(1).expiredUrl("/admin/toLogin");
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(this.hashPasswordEncoder);
    }

    @Override
    public void configure(WebSecurity web) {
        web.ignoring().antMatchers("/js/**","/layui/**","/css/**","/layer/**","/img/**","/image/**","/picture/**","/images/**","/bootstrap/**","/favicon.ico","/goods/**","/imgs/**");
    }
}
